/**
* Live preview script for MediaWiki
*/
-(function( $ ) {
- window.doLivePreview = function( e ) {
- var previewShowing = false;
-
+( function( mw, $ ) {
+ var doLivePreview = function( e ) {
e.preventDefault();
$( mw ).trigger( 'LivePreviewPrepare' );
var $wikiPreview = $( '#wikiPreview' );
- $( '#mw-content-text' ).css( 'position', 'relative' );
-
+ // this needs to be checked before we unconditionally show the preview
+ var previewVisible = false;
if ( $wikiPreview.is( ':visible' ) ) {
- previewShowing = true;
+ previewVisible = true;
}
- // show #wikiPreview if it's hidden (if it is hidden, it's also empty, so nothing changes in the rendering)
- // to be able to scroll to it
+ // show #wikiPreview if it's hidden to be able to scroll to it
+ // (if it is hidden, it's also empty, so nothing changes in the rendering)
$wikiPreview.show();
-
- // Jump to where the preview will appear
+ // jump to where the preview will appear
$wikiPreview[0].scrollIntoView();
- var postData = $('#editform').formToArray(); // formToArray: from jquery.form
- postData.push( { 'name' : e.target.name, 'value' : '1' } );
-
- // Hide active diff, used templates, old preview if shown
- var copyElements = ['#wikiPreview', '#wikiDiff', '.templatesUsed', '.hiddencats',
- '#catlinks', '#p-lang', '.mw-summary-preview'];
- var copySelector = copyElements.join(',');
+ // list of elements that will be loaded from the preview page
+ var copySelectors = [
+ '#wikiPreview', '#wikiDiff', '#catlinks', '.hiddencats', '#p-lang', // the meat
+ '.templatesUsed', '.mw-summary-preview' // editing-related
+ ];
+ var $copyElements = $( copySelectors.join( ',' ) );
- $.each( copyElements, function( k, v ) {
- $( v ).fadeTo( 'fast', 0.4 );
- } );
+ var $loadSpinner = $( '<div>' ).addClass( 'mw-ajax-loader' );
+ $loadSpinner.css( 'top', '0' ); // move away from header (default is -16px)
- // Display a loading graphic
- var loadSpinner = $('<div class="mw-ajax-loader"/>');
- // Move away from header (default is -16px)
- loadSpinner.css( 'top', '0' );
+ // If the preview is already visible, overlay the spinner on top of it.
+ if ( previewVisible ) {
+ $( '#mw-content-text' ).css( 'position', 'relative' ); // FIXME this seems like a bad idea
- // If the preview is already showing, overlay the spinner on top of it.
- if ( previewShowing ) {
- loadSpinner.css( {
+ $loadSpinner.css( {
'position': 'absolute',
'z-index': '3',
'left': '50%',
'margin-left': '-16px'
} );
}
- $wikiPreview.before( loadSpinner );
- var page = $('<div/>');
- var target = $('#editform').attr('action');
+ // fade out the elements and display the throbber
+ $( '#mw-content-text' ).prepend( $loadSpinner );
+ // we can't use fadeTo because it calls show(), and we might want to keep some elements hidden
+ // (e.g. empty #catlinks)
+ $copyElements.animate( { 'opacity': 0.4 }, 'fast' );
- if ( !target ) {
- target = window.location.href;
- }
+ var $previewDataHolder = $( '<div>' );
+ var target = $( '#editform' ).attr( 'action' ) || window.location.href;
- page.load( target + ' ' + copySelector, postData,
- function() {
-
- for( var i=0; i<copyElements.length; ++i) {
- // For all the specified elements, find the elements in the loaded page
- // and the real page, empty the element in the real page, and fill it
- // with the content of the loaded page
- var copyContent = page.find( copyElements[i] ).contents();
- $(copyElements[i]).empty().append( copyContent );
- var newClasses = page.find( copyElements[i] ).prop('class');
- $(copyElements[i]).prop( 'class', newClasses );
- }
-
- $.each( copyElements, function( k, v ) {
- // Don't belligerently show elements that are supposed to be hidden
- $( v ).fadeTo( 'fast', 1, function() {
- $( this ).css( 'display', '' );
- } );
- } );
-
- loadSpinner.remove();
-
- $( mw ).trigger( 'LivePreviewDone', [copyElements] );
- } );
+ // gather all the data from the form
+ var postData = $( '#editform' ).formToArray(); // formToArray: from jquery.form
+ postData.push( { 'name' : e.target.name, 'value' : '1' } );
+
+ // load new preview data
+ // FIXME this should use the action=parse API instead of loading the entire page
+ $previewDataHolder.load( target + ' ' + copySelectors.join( ',' ), postData, function() {
+ // Copy the contents of the specified elements from the loaded page to the real page.
+ // Also copy their class attributes.
+ for ( var i = 0; i < copySelectors.length; i++ ) {
+ var $from = $previewDataHolder.find( copySelectors[i] );
+ var $to = $( copySelectors[i] );
+
+ $to.empty().append( $from.contents() );
+ $to.attr( 'class', $from.attr( 'class' ) );
+ }
+
+ $loadSpinner.remove();
+ $copyElements.animate( { 'opacity': 1 }, 'fast' );
+
+ $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
+ } );
};
- $(document).ready( function() {
- // construct space for interwiki links if missing
- // (it is usually not shown when action=edit, but shown if action=submit)
+ $( document ).ready( function() {
+ // construct the elements we need if they are missing (usually when action=edit)
+ // we don't need to hide them, because they are empty when created
+
+ // interwiki links
if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
- // we need not hide this, because it's empty anyway
$( '#p-tb' ).after( $( '<div>' ).attr( 'id', 'p-lang' ) );
}
- // construct space for summary preview if missing
+ // summary preview
if ( $( '.mw-summary-preview' ).length === 0 ) {
$( '.editCheckboxes' ).before( $( '<div>' ).addClass( 'mw-summary-preview' ) );
}
- // construct space for diff if missing. also load diff styles.
+ // diff
if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
$( '#wikiPreview' ).after( $( '<div>' ).attr( 'id', 'wikiDiff' ) );
- // diff styles are by default only loaded when needed
- // if there was no diff container, we can expect the styles not to be there either
- mw.loader.load( 'mediawiki.action.history.diff' );
}
+ // diff styles are usually only loaded during, well, diff, and we might need them
+ // (mw.loader takes care of stuff if they happen to be loaded already)
+ mw.loader.load( 'mediawiki.action.history.diff' );
+
$( '#wpPreview, #wpDiff' ).click( doLivePreview );
} );
-}) ( jQuery );
+} )( mediaWiki, jQuery );